//!
/**
 ***********************************************************************************************************
 * <RBMaterial Implementation>
 ***********************************************************************************************************
 * @file RBMaterial.cpp
 ***********************************************************************************************************/

/***********************************************************************************************************
 * Precompiled Header
 ***********************************************************************************************************/
#include "RBMainPCH.h"

/***********************************************************************************************************
 * Includes
 ***********************************************************************************************************/
#include "RBMaterial.h"
#include "RBRenderProcess/RBEffect.h"
#include "RBRenderProcess/RBEffectFactory.h"

/***********************************************************************************************************
 * Defines
 ***********************************************************************************************************/

/***********************************************************************************************************
 * Classes implementation
 ***********************************************************************************************************/

/**
 ***********************************************************************************************************
 * Constructor
 ***********************************************************************************************************/
RBMaterial::RBMaterial()
: Super()
, Ambient(1,1,1)
, Diffuse(1,1,1)
, Specular(1,1,1)
, Emissive(0.0f,0.0f,0.0f)
, Shininess(1)
, Opacity(1)
, Multiplier(1)
, IsAlphaTested(false)
, AlphaRef(128)
, m_pEffect(NULL)
, m_uiTechnique(0)
{
    BlendState.Mask = 0;
    BlendState.IsAlphaBlended = false;
    BlendState.SrcBlend = AF_ONE;
    BlendState.DestBlend = AF_ZERO;
    BlendState.BlendOp = BO_ADD;
    BlendState.SrcBlendAlpha = AF_ONE;
    BlendState.DestBlendAlpha = AF_ZERO;
    BlendState.BlendOpAlpha = BO_ADD;

    RasterState.Mask = 0;
    RasterState.IsWireframe = false;
    RasterState.FrontCounterClockwise = true;
    RasterState.Cull = MCM_NONE
        ;

    DepthState.Mask = 0;
    DepthState.ZEnable = true;
    DepthState.ZWriteEnable = true;
    DepthState.ZFunc = CF_LESS_EQUAL;

    DepthState.StencilEnable = false;
    DepthState.StencilMask = 0xFF;
    DepthState.StencilWriteMask = 0xFF;
    DepthState.StencilRef = 0x00;

    DepthState.StencilFrontFaceFunc = CF_ALWAYS;
    DepthState.StencilFrontFacePassOp = SO_KEEP;
    DepthState.StencilFrontFaceFailOp = SO_KEEP;
    DepthState.StencilFrontFaceDepthFailOp = SO_KEEP;

    DepthState.StencilBackFaceFunc = CF_ALWAYS;
    DepthState.StencilBackFacePassOp = SO_KEEP;
    DepthState.StencilBackFaceFailOp = SO_KEEP;
    DepthState.StencilBackFaceDepthFailOp = SO_KEEP;

}

/**
 ***********************************************************************************************************
 * Destructor
 ***********************************************************************************************************/
RBMaterial::~RBMaterial()
{
}

/**************************************************************************************************************************************************************
 * 
 **************************************************************************************************************************************************************/
void RBMaterial::CopyMembers(RBMaterial* pDest)
{
    pDest->Ambient        = Ambient;
    pDest->Diffuse        = Diffuse;
    pDest->Specular       = Specular;
    pDest->Emissive       = Emissive;
    pDest->Shininess      = Shininess;
    pDest->Opacity        = Opacity;
    pDest->BlendState     = BlendState;
    pDest->RasterState    = RasterState;
    pDest->DepthState     = DepthState;
    pDest->IsAlphaTested  = IsAlphaTested;
    pDest->AlphaRef       = AlphaRef;
    pDest->DataContainer  = DataContainer;
    pDest->m_pEffect = m_pEffect;
    pDest->m_uiTechnique = m_uiTechnique;
}

/***********************************************************************************************************
 * 
 ***********************************************************************************************************/
void RBMaterial::Serialize(RBStream& rbStream)
{
    rbStream & Ambient;
    rbStream & Diffuse;
    rbStream & Specular;
    rbStream & Emissive;

    rbStream & Shininess & Opacity & BlendState.Mask & RasterState.Mask & DepthState.Mask & IsAlphaTested & AlphaRef;

#pragma TODO("Serialize samplers properly")

    bool bHasTechnique = (m_pEffect != NULL);
    rbStream & bHasTechnique;
    RBString strTechniqueName = m_pEffect ? m_pEffect->Name : "";
    rbStream & strTechniqueName;
    if (rbStream.IsReading())
    {
        m_pEffect = RBEffectFactory::GetSingleton()->RetrieveEffect(strTechniqueName);
    }
    
    rbStream & m_uiTechnique;

}
/***********************************************************************************************************/
